home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / NET / PROFILE.H < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  7.8 KB  |  312 lines

  1. #include <linux/config.h> /* for CONFIG_NET_PROFILE */
  2. #ifndef _NET_PROFILE_H_
  3. #define _NET_PROFILE_H_ 1
  4.  
  5. #ifdef CONFIG_NET_PROFILE
  6.  
  7. #include <linux/types.h>
  8. #include <linux/time.h>
  9. #include <linux/kernel.h>
  10. #include <asm/system.h>
  11.  
  12. struct net_profile_slot
  13. {
  14.     char   id[16];
  15.     struct net_profile_slot *next;
  16.     struct timeval entered;
  17.     struct timeval accumulator;
  18.     struct timeval irq;
  19.     int        hits;
  20.     int        active;
  21.     int    underflow;
  22. };
  23.  
  24. extern atomic_t net_profile_active;
  25. extern struct timeval net_profile_adjust;
  26. extern void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved);
  27.  
  28. #if CPU == 586 || CPU == 686
  29.  
  30.  
  31. extern __inline__ void  net_profile_stamp(struct timeval *pstamp)
  32. {
  33.     __asm__ __volatile__ (".byte 0x0f,0x31"
  34.         :"=a" (pstamp->tv_usec),
  35.         "=d" (pstamp->tv_sec));
  36. }
  37.  
  38. extern __inline__ void  net_profile_accumulate(struct timeval *entered,
  39.                            struct timeval *leaved,
  40.                            struct timeval *acc)
  41. {
  42.     __asm__ __volatile__ ("subl %2,%0\n\t" 
  43.                   "sbbl %3,%1\n\t" 
  44.                   "addl %4,%0\n\t" 
  45.                   "adcl %5,%1\n\t" 
  46.                   "subl " SYMBOL_NAME_STR(net_profile_adjust) "+4,%0\n\t" 
  47.                   "sbbl $0,%1\n\t" 
  48.                   : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  49.                   : "g" (entered->tv_usec), "g" (entered->tv_sec),
  50.                   "g" (leaved->tv_usec), "g" (leaved->tv_sec),
  51.                   "0" (acc->tv_usec), "1" (acc->tv_sec));
  52. }
  53.  
  54. extern __inline__ void  net_profile_sub(struct timeval *sub,
  55.                     struct timeval *acc)
  56. {
  57.     __asm__ __volatile__ ("subl %2,%0\n\t" 
  58.                   "sbbl %3,%1\n\t" 
  59.                   : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  60.                   : "g" (sub->tv_usec), "g" (sub->tv_sec),
  61.                   "0" (acc->tv_usec), "1" (acc->tv_sec));
  62. }
  63.  
  64. extern __inline__ void  net_profile_add(struct timeval *add,
  65.                     struct timeval *acc)
  66. {
  67.     __asm__ __volatile__ ("addl %2,%0\n\t" 
  68.                   "adcl %3,%1\n\t" 
  69.                   : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  70.                   : "g" (add->tv_usec), "g" (add->tv_sec),
  71.                   "0" (acc->tv_usec), "1" (acc->tv_sec));
  72. }
  73.  
  74.  
  75. #elif defined (__alpha__)
  76.  
  77. extern __u32 alpha_lo;
  78. extern long alpha_hi;
  79.  
  80. /* On alpha cycle counter has only 32 bits :-( :-( */
  81.  
  82. extern __inline__ void  net_profile_stamp(struct timeval *pstamp)
  83. {
  84.     __u32 result;
  85.     __asm__ __volatile__ ("rpcc %0" : "r="(result));
  86.     if (result <= alpha_lo)
  87.         alpha_hi++;
  88.     alpha_lo = result;
  89.     pstamp->tv_sec = alpha_hi;
  90.     pstamp->tv_usec = alpha_lo;
  91. }
  92.  
  93. extern __inline__ void  net_profile_accumulate(struct timeval *entered,
  94.                            struct timeval *leaved,
  95.                            struct timeval *acc)
  96. {
  97.     time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
  98.         - net_profile_adjust.tv_usec;
  99.     time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
  100.  
  101.     if (usecs >= 0x100000000L) {
  102.         usecs -= 0x100000000L;
  103.         secs++;
  104.     } else if (usecs < -0x100000000L) {
  105.         usecs += 0x200000000L;
  106.         secs -= 2;
  107.     } else if (usecs < 0) {
  108.         usecs += 0x100000000L;
  109.         secs--;
  110.     }
  111.     acc->tv_sec = secs;
  112.     acc->tv_usec = usecs;
  113. }
  114.  
  115. extern __inline__ void  net_profile_sub(struct timeval *entered,
  116.                     struct timeval *leaved)
  117. {
  118.     time_t usecs = leaved->tv_usec - entered->tv_usec;
  119.     time_t secs = leaved->tv_sec - entered->tv_sec;
  120.  
  121.     if (usecs < 0) {
  122.         usecs += 0x100000000L;
  123.         secs--;
  124.     }
  125.     leaved->tv_sec = secs;
  126.     leaved->tv_usec = usecs;
  127. }
  128.  
  129. extern __inline__ void  net_profile_add(struct timeval *entered, struct timeval *leaved)
  130. {
  131.     time_t usecs = leaved->tv_usec + entered->tv_usec;
  132.     time_t secs = leaved->tv_sec + entered->tv_sec;
  133.  
  134.     if (usecs >= 0x100000000L) {
  135.         usecs -= 0x100000000L;
  136.         secs++;
  137.     }
  138.     leaved->tv_sec = secs;
  139.     leaved->tv_usec = usecs;
  140. }
  141.  
  142.  
  143. #else
  144.  
  145. extern __inline__ void  net_profile_stamp(struct timeval *pstamp)
  146. {
  147.     /* Not "fast" counterpart! On architectures without
  148.        cpu clock "fast" routine is absolutely useless in this
  149.        situation. do_gettimeofday still says something on slow-slow-slow
  150.        boxes, though it eats more cpu time than the sobject of
  151.        investigation :-) :-)
  152.      */
  153.     do_gettimeofday(pstamp);
  154. }
  155.  
  156. extern __inline__ void  net_profile_accumulate(struct timeval *entered,
  157.                            struct timeval *leaved,
  158.                            struct timeval *acc)
  159. {
  160.     time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
  161.         - net_profile_adjust.tv_usec;
  162.     time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
  163.  
  164.     if (usecs >= 1000000) {
  165.         usecs -= 1000000;
  166.         secs++;
  167.     } else if (usecs < -1000000) {
  168.         usecs += 2000000;
  169.         secs -= 2;
  170.     } else if (usecs < 0) {
  171.         usecs += 1000000;
  172.         secs--;
  173.     }
  174.     acc->tv_sec = secs;
  175.     acc->tv_usec = usecs;
  176. }
  177.  
  178. extern __inline__ void  net_profile_sub(struct timeval *entered,
  179.                     struct timeval *leaved)
  180. {
  181.     time_t usecs = leaved->tv_usec - entered->tv_usec;
  182.     time_t secs = leaved->tv_sec - entered->tv_sec;
  183.  
  184.     if (usecs < 0) {
  185.         usecs += 1000000;
  186.         secs--;
  187.     }
  188.     leaved->tv_sec = secs;
  189.     leaved->tv_usec = usecs;
  190. }
  191.  
  192. extern __inline__ void  net_profile_add(struct timeval *entered, struct timeval *leaved)
  193. {
  194.     time_t usecs = leaved->tv_usec + entered->tv_usec;
  195.     time_t secs = leaved->tv_sec + entered->tv_sec;
  196.  
  197.     if (usecs >= 1000000) {
  198.         usecs -= 1000000;
  199.         secs++;
  200.     }
  201.     leaved->tv_sec = secs;
  202.     leaved->tv_usec = usecs;
  203. }
  204.  
  205.  
  206.  
  207. #endif
  208.  
  209. extern __inline__ void net_profile_enter(struct net_profile_slot *s)
  210. {
  211.     unsigned long flags;
  212.  
  213.     save_flags(flags);
  214.     cli();
  215.     if (s->active++ == 0) {
  216.         net_profile_stamp(&s->entered);
  217.         atomic_inc(&net_profile_active);
  218.     }
  219.     restore_flags(flags);
  220. }
  221.  
  222. extern __inline__ void net_profile_leave_irq(struct net_profile_slot *s)
  223. {
  224.     unsigned long flags;
  225.  
  226.     save_flags(flags);
  227.     cli();
  228.     if (--s->active <= 0) {
  229.         if (s->active == 0) {
  230.             struct timeval curr_pstamp;
  231.             net_profile_stamp(&curr_pstamp);
  232.             net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
  233.             if (!atomic_dec_and_test(&net_profile_active))
  234.                 net_profile_irq_adjust(&s->entered, &curr_pstamp);
  235.         } else {
  236.             s->underflow++;
  237.         }
  238.     }
  239.     s->hits++;
  240.     restore_flags(flags);
  241. }
  242.  
  243. extern __inline__ void net_profile_leave(struct net_profile_slot *s)
  244. {
  245.     unsigned long flags;
  246.     save_flags(flags);
  247.     cli();
  248.     if (--s->active <= 0) {
  249.         if (s->active == 0) {
  250.             struct timeval curr_pstamp;
  251.             net_profile_stamp(&curr_pstamp);
  252.             net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
  253.             atomic_dec(&net_profile_active);
  254.         } else {
  255.             s->underflow++;
  256.         }
  257.     }
  258.     s->hits++;
  259.     restore_flags(flags);
  260. }
  261.  
  262.  
  263. #define NET_PROFILE_ENTER(slot) net_profile_enter(&net_prof_##slot)
  264. #define NET_PROFILE_LEAVE(slot) net_profile_leave(&net_prof_##slot)
  265. #define NET_PROFILE_LEAVE_IRQ(slot) net_profile_leave_irq(&net_prof_##slot)
  266.  
  267. #define NET_PROFILE_SKB_CLEAR(skb) ({ \
  268.  skb->pstamp.tv_usec = 0; \
  269. })
  270.  
  271. #define NET_PROFILE_SKB_INIT(skb) ({ \
  272.  net_profile_stamp(&skb->pstamp); \
  273. })
  274.  
  275. #define NET_PROFILE_SKB_PASSED(skb, slot) ({ \
  276.  if (skb->pstamp.tv_usec) { \
  277.    struct timeval cur_pstamp = skb->pstamp; \
  278.    net_profile_stamp(&skb->pstamp); \
  279.    net_profile_accumulate(&cur_pstamp, &skb->pstamp, &net_prof_##slot.accumulator); \
  280.    net_prof_##slot.hits++; \
  281.  }})
  282.  
  283. #define NET_PROFILE_DECL(slot) \
  284.   extern struct net_profile_slot net_prof_##slot;
  285.  
  286. #define NET_PROFILE_DEFINE(slot) \
  287.   struct net_profile_slot net_prof_##slot = { #slot, };
  288.  
  289. #define NET_PROFILE_REGISTER(slot) net_profile_register(&net_prof_##slot)
  290. #define NET_PROFILE_UNREGISTER(slot) net_profile_unregister(&net_prof_##slot)
  291.  
  292. extern int net_profile_init(void);
  293. extern int net_profile_register(struct net_profile_slot *);
  294. extern int net_profile_unregister(struct net_profile_slot *);
  295.  
  296. #else
  297.  
  298. #define NET_PROFILE_ENTER(slot) do { /* nothing */ } while(0)
  299. #define NET_PROFILE_LEAVE(slot) do { /* nothing */ } while(0)
  300. #define NET_PROFILE_LEAVE_IRQ(slot) do { /* nothing */ } while(0)
  301. #define NET_PROFILE_SKB_CLEAR(skb) do { /* nothing */ } while(0)
  302. #define NET_PROFILE_SKB_INIT(skb) do { /* nothing */ } while(0)
  303. #define NET_PROFILE_SKB_PASSED(skb, slot) do { /* nothing */ } while(0)
  304. #define NET_PROFILE_DECL(slot)
  305. #define NET_PROFILE_DEFINE(slot)
  306. #define NET_PROFILE_REGISTER(slot) do { /* nothing */ } while(0)
  307. #define NET_PROFILE_UNREGISTER(slot) do { /* nothing */ } while(0)
  308.  
  309. #endif
  310.  
  311. #endif
  312.